package com.wang.interview.tests.CASandVolatile;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author: wang
 * @date: 2021/8/8 20:58
 * @description: 第二次修改失败，因为版本号被第一个线程修改成了2，与期望的1不同，导致修改失败，即解决了ABA问题
 */
public class ABA {

    public static void main(String[] args) {
        ExecutorService pool = new ThreadPoolExecutor(2,4,10, TimeUnit.SECONDS,new LinkedBlockingQueue<>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());
        AtomicStampedReference<Integer> atomicInteger
                = new AtomicStampedReference<>(100, 1);
        pool.submit(()->{
            int stamp = atomicInteger.getStamp();
            System.out.println(stamp);
            Integer reference = atomicInteger.getReference();
            try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            boolean b = atomicInteger.compareAndSet(reference, reference + 100
                    , stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName() + "修改结果为："+b+", expect修改后的值: "+atomicInteger.getReference()+"stamp:"+atomicInteger.getStamp());
            boolean b1 = atomicInteger.compareAndSet(atomicInteger.getReference(), reference,atomicInteger.getStamp(),atomicInteger.getStamp()+1);
            System.out.println("模拟ABA将stamp改回1，当前stamp的值为："+b1+atomicInteger.getStamp());
        },"t1");

        pool.submit(()->{
            int stamp = atomicInteger.getStamp();
            System.out.println(stamp);
            Integer reference = atomicInteger.getReference();
            try {TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            boolean b = atomicInteger.compareAndSet(reference, reference + 100
                    , stamp, stamp + 1);
            System.out.println(Thread.currentThread().getName() + "修改结果为："+b+", expect修改后的值: "+atomicInteger.getReference()+"stamp:"+atomicInteger.getStamp());
        },"t1");

        pool.shutdown();
    }
}
class T1{

}